#pragma once

#include "Part.h"
#include "Common/MissionDefine.h"

class MissionPart : public Part
{
	friend class MissionEntry;

	//任务章节保存结构
	struct SaveInfo
	{
		uint32_t k;
		uint32_t v;
		SaveInfo(){ k = 0; v = 0; }
		bool Add(uint32_t chapter)
		{
			uint32_t r = chapter / 32;
			r = r * 32;
			bool isnew = (r != k);
			if (isnew){ k = r; v = 0; }
			r = chapter - k;
			int32_t t = (int32_t)r;
			v = (uint32_t)((1 << t) | v);
			return isnew;
		}
	};
	//
	typedef unordered_map<uint32_t,SaveInfo> MAPSAVE;
	static void DecodeSave(MAPSAVE &mapsave, SET_UINT32 &setChapter);
	static void EncodeSave(SET_UINT32 &setChapter, MAPSAVE &mapsave);

public:
	typedef std::map<uint32_t, uint32_t>							Map;
	typedef std::unordered_set<uint32_t>							Set;
	//typedef std::map<uint32_t, Set >								EventTabal;
	// eventtype - level - dynamicid
	typedef std::unordered_map<uint32_t, MAP_INT32_SET_UINT32 >		EventTabal;


	typedef std::map<uint32_t, MissionFinishInfo>					FinishMissionList;
	typedef std::map<uint32_t, MissionTrack*>						PlayerTrackMissionMap;
	typedef std::queue<ExecuteData>									EventQueue;
	typedef std::multimap<uint32_t, uint32_t>						MulMap;
	typedef std::map<uint32_t, MissionCampInfo>						PlayerCampMissionMap;
	typedef std::set<AbandonUnit>									AbandonUnitSet;
	typedef std::map<uint32_t, MissionBountyInfo>					PlayerBountyMissionMap;
	typedef std::unordered_map<int32_t, DyMissionTrack>				PlayerDyMissionTrackMap;
	typedef std::list<RecentSubmitTrunk>							RecentSubmitTrunkList;
public:
	MissionPart();
	virtual ~MissionPart();

public:
	virtual bool		Init(Creature *pMaster, uint32_t partType, CharacterDBInfo* pCharacterDB = nullptr);
	virtual bool		UnInit();
	virtual bool		OnMsgHandle(uint32_t cmd, const char* data, uint32_t len);
	virtual void		OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen);
	virtual void		OnTimer(uint32_t nTimerID){}
	virtual bool		SaveDB(CharacterDBInfo& characterDB);
	virtual void		Update(uint64_t tick);
	//角色登录
	virtual bool		SynOnLogin();
	//角色下线
	virtual void		SynLogout();
	//生物切换逻辑节点
	virtual void OnChangeLogic();
	//角色升级
	void				OnLevelUp();
	void				OnCampChange();
	void				OnPassDuplicate(void* pContext);
	void				OnEquipStren(void* pContext);
	void				OnGodLevelUp(void* pContext);
	void				OnStoneInlay(void* pContext);
	void				OnEquipReFine(void* pContext); 
	void				OnRuneInlay(void* pContext);
	void				OnDeputyCollect(void* pContext);
	void				OnDeputyMake(void* pContext);
	void				OnDeputyForge(void* pContext);
	void				OnItemChange(void* pContext);
	void				OnAddBuff(void* pContext);
	void				OnAddFriend();
	void				OnUseThingFinish(void* pContext);
	void				OnLeaveBanishMap(void* pContext);
	void				OnEnterBanishMap(void *pContext);
	void				OnEnterArena(void *pContext);
	void				OnGuildChange(void *pContext);
	void				OnGuildFightLevel(void *pContext);
	void				OnGuildEscortFinish(void *pContext);
	void				OnGuildRunBusiness(void *pContext);
	void				OnSkillLevel(void *pContext);
	void				OnClearAttrPoint(void *pContext);

	//任务每日零点更新
	virtual bool DailyUpdate(uint64_t unixSec);
	//任务每周零点更新
	virtual bool WeekUpdate(uint64_t unixSec);

public: //消息回调接口
	void				HandleNpcAcceptMission(const char* data, uint32_t len);					//NPC接取任务
	void				HandleAbandonMission(const char* data, uint32_t len);					//放弃任务
	void				HandleSubmitMission(const char* data, uint32_t len);					//提交任务
	void				HandleTalkWithNpc(const char* data, uint32_t len);						//NPC对话,寻人接口
	void				HandleSelMission(const char* data, uint32_t len);						//分支选择任务
	//阵营任务
	void				HandleGetCampMissionInfo(const char* data, uint32_t len);				//获取阵营任务列表
	void				HandleDiceCampMission(const char* data, uint32_t len);					//摇筛子
	void				HandleGetCampBoxReward(const char* data, uint32_t len);					//
	void				HandleMissionAnswer(const char* data, uint32_t len);					//任务答题
	//赏金任务
	void				HandleGetBountyMissionInfo(const char* data, uint32_t len);				//获取赏金任务列表
	void				HandleUpdateBountyMissionInfo(const char* data, uint32_t len);			//刷新赏金任务列表
	//工会任务
	void				HandleRefreshGuildMission(const char* data, uint32_t len);				//刷新工会任务

	void				HandleSubmitMissionGoods(const char* data, uint32_t len);				//提交任务物品

	/////////////////////////////////////////普通任务接口/////////////////////////////////////////////
	int32_t				AcceptMissionByType(int32_t missionType, bool notify);			//通过任务类型接取任务
	void				ClearMissionByType(int32_t missionType, bool notify);			//通过任务类型清除任务
	void				ClearMissionByCampChange(bool notify);							//通过改变阵营清除任务
	void				ClearMissionByActTime(int32_t missionType, bool notify);		//通过活动时间清除任务
	void				SendMissionList(const char* data, uint32_t len);				//推送任务列表信息
	void				InitCampMission(bool bRefresh = false, bool bNotify = true);	//初始阵营任务相关信息
	///////////////////////////////////////赏金任务接口////////////////////////////////////////////////
	ERetCode			InitBountyMission(uint32_t npcId, bool bRefresh = false);
	void				UpdateBountyMission(uint32_t nowTime);

	///////////////////////////////////////作弊接口///////////////////////////////////////////////////
	ERetCode			CheatAcceptMission(const uint32_t& missionId);
	ERetCode			CheatFastFinishMission(const uint32_t& beginMissionId, const uint32_t& endMissionId);
	ERetCode			CheatSubmitMission(const uint32_t& missionId);
	ERetCode			CheatFastFinishSigleMission(const uint32_t& missionId,bool notify = true);
	ERetCode			CheatRemoveSingleMissiion(const uint32_t& missionId, bool notify = true);

	////////////////////////////// 新的任务接口 ////////////////////////////////////////////
	//更新任务进度
	void				UpdateMissionProgress(uint32_t missionId);
	//删除任务
	void				NotifyDelMission(uint32_t dymissionId);
	//更新可接列表
	bool				HaveAccpet(const uint32_t& missionId);									//该任务是否已经接收过了
	bool				HaveChapterSubmit(const uint32_t& chapterId);							//该章节是否已经提交过了
	bool				HaveFinish(const uint32_t& missionId);									//判断某个任务是否完成了
	bool				HaveNoFinish(const uint32_t& missionId);								//判断某个任务是否已接取并且没完成
	int32_t				MissionNumByType(int32_t missionType);									//根据任务类型获取当前任务列表中存在的数量
	void				MissionLstByType(int32_t missionType,SET_UINT32 &setAccept);			//根据任务类型获取当前任务列表中存在的任务ID
	int32_t				HaveFinishNumByType(int32_t missionType);								//根据任务类型获取已完成的次数
	void				SetDyMissionTrack(int32_t missionType, int32_t finishNum, uint64_t lastFresh);//设置动态任务数据
	uint32_t			AllocNewDyMisssionId();													//分配一个动态任务ID
	void				FreeDyMissionId(uint32_t dyMissionId);									//回收一个动态任务ID
	bool				ValidDyMissionId(uint32_t dyMissionId);									//是否是有效的动态任务ID
	void				CheckCampMission(bool bFresh,bool notify);								//检查阵营任务
	void				CheckGuildMission(bool notify = false);									//检查工会任务
	void				CheckGuildDailyMission(bool notify = false);							//检查工会日常任务
	void				CheckBanishMission(bool notify = false);								//检查流放之地任务
	void				CheckActCollectMission(bool notify = false);							//检查活动收集任物
	bool				IsNeedFresh(uint64_t nowTime, int32_t missionType, uint64_t lastTime);	//指定任务类型是否需要重置
	void				CheckMissionFresh();													//检查任务重置
	void				MissionFresh(int32_t missionType, uint64_t nowTime);					//重置制定任务类型的任务
	uint64_t			GetMissionFreshTime(int32_t missionType);								//根据任务类型获取刷新时间
	void				OnSubmit(uint32_t missionId, uint32_t backMissionId,uint32_t chapterId, uint32_t kind);//提交任务
	void				OnAbandon(uint32_t chapterId);											//放弃任务
	void				OnSubmitDy(uint32_t dymissionId, int32_t missionType, int32_t quality);	//提交任务(动态任务)
	void				OnFinishDy(uint32_t dymissionId);										//完成任务(动态任务)
	void				OnAbandonDy(uint32_t dymissionId, int32_t missionType);					//放弃任务(动态任务)
	bool				AddMissionDrop(uint32_t dymissionId, uint32_t monsId, uint32_t dropId, uint32_t boxId,int32_t progressLev);//添加任务掉落
	bool				DelMissionDrop(uint32_t dymissionId, uint32_t monsId);					//删除任务掉落
	void				GetMissionDrop(uint32_t monsterId, MissionDropMap &mapMissionDrop);		//获取任务掉落
	bool				AcceptMissionByUseItem(uint32_t chapterId);								//使用物品接取任务
	bool				AcceptMissionByEffect(uint32_t chapterId);								//效果触发器触发接取任务
	int32_t				AcceptMissionByAdventure(uint32_t chapterId);							//奇遇系统 接取任务
	void				SetMissionOpen(int32_t missionType,bool openFlag);						//设置任务开启
	bool				MissionOpen(int32_t missionType);										//任务是否开启
	void				OnActivityState(uint32_t actId);										//活动状态更新
	void				CheckMissionTimeout(bool notify = true);								//检查任务超时
	bool				HaveAcceptChapter(const uint32_t &chapterId);							//是否已接取过章节
	void				CheckTrunkMission(bool notify = true);									//检查主线任务
	void				ShareKillMons(uint32_t monsId, CharIDType killerCid, int32_t monsLev, int32_t count, Point3<float> &pos);//共享杀怪
	void				MissionDropByKillMons(uint32_t monsId, int32_t monsLev, Point3<float> &pos);//杀怪掉落
public://任务事件处理接口
	void				RegisterEvent(const uint32_t& eventType, const uint32_t& missionId,int32_t progressLev);//注册监听事件，接任务成功后注册
	void				RemoveEvent(const uint32_t& missionId);									//移除这个任务注册的所有事件
	void				OnEvent(const uint32_t& eventType, const ExecuteData& data);			//发送任务事件，阻塞

private://游戏通用事件处理接口
	void				OnDie();
	void				OnMonsterDie(DieEvent& dieEvent);
	void				OnAreaFreshMonster(uint32_t dymissionId);	
	void				ShareMissionDropByKillMons(uint32_t monsId, int32_t monsLev, int32_t count, Point3<float> &pos);	//杀怪共享任务掉落
private: //任务内部接口
	void OnLogin(); //登录的处理
	void CheckMissionOpen(int32_t missionType); //检查任务开启
	void CheckAllMissionOpen();					//检查所有任务开启
	void UpdateRecentSubmitTrunk(uint32_t missionId, int32_t camp, int32_t race);//更新最近提交的主线任务
	uint32_t GetRecentSubmitTrunk(int32_t camp, int32_t race);//获取最近提交的主线任务
private:
	uint32_t							 _aryDyIdAlloc[MISSION_MAX_DYNAMIC_ALLOC + 1]; //动态任务ID分配
	uint64_t							 _lastCheckTimeout;	//最近一次检测任务超时的时间
public:
	PlayerTrackMissionMap				_playerTrackMissionMap;	//当前任务列表
	SET_UINT32							_setSubmitChapter;		//已经提交的章节
	RecentSubmitTrunkList				_lstRecentSubmit;		//最近提交的主线任务
	//动态任务
	PlayerDyMissionTrackMap				_mapDyMissionTrack;		//动态任务数据
	MissionAllDropMap					_mapMissionAllDrop;		//任务掉落

	MAP_UINT32_INT32					_mapDyCompleteCount;	//动态任务周期内已经完成的次数 动态任务配置ID-次数
	MAP_UINT32_UINT64					_mapDyFreshtime;		//动态任务刷新时间	
	//阵营
	PlayerTrackMissionMap				_mapCampCanAccept;		//阵营可接任务列表
	uint32_t							_campBoxProgress;		//阵营宝箱进度
	uint32_t							_campExtraceTimes;		//阵营抽取的次数
	//赏金
	PlayerTrackMissionMap				_mapBountyCanAccept;	//赏金可接任务列表
	uint32_t							_bountyFreeNum;			//使用了多少次免费刷新次数
	uint32_t							_bountyAccetpNum;		//周期内接取了多少个赏金任务
	//任务开启标志
	MAP_INT32_INT8						_mapMissionOpen;		//任务开启标志
	//
	EventTabal							_eventTabal;			//任务事件表
};
